package com.tongji.housediy.view.components
{
	import com.tongji.housediy.events.SetShowNameEnable;
	import com.tongji.housediy.events.UpdateRatioCompEvent;
	import com.tongji.housediy.events.commonEvent.BeginDrawFreeFloorEvent;
	import com.tongji.housediy.events.commonEvent.CursorBitmapEvent;
	import com.tongji.housediy.events.commonEvent.ExchangeDataEvent;
	import com.tongji.housediy.events.commonEvent.GridContainerEvent;
	import com.tongji.housediy.events.commonEvent.MouseEnabledAdminEvent;
	import com.tongji.housediy.events.commonEvent.RelatedRoomAdminEvent;
	import com.tongji.housediy.events.commonEvent.RoomNameAdminEvent;
	import com.tongji.housediy.events.commonEvent.RotationRelatedEvent;
	import com.tongji.housediy.events.commonEvent.RulerAdminEvent;
	import com.tongji.housediy.events.commonEvent.SetCompStateEvent;
	import com.tongji.housediy.events.commonEvent.ShowHideFilterEvent;
	import com.tongji.housediy.events.commonEvent.ShowHideTitleWindowEvent;
	import com.tongji.housediy.events.commonEvent.ShowVertexEvent;
	import com.tongji.housediy.model.ExchangeDataModel;
	import com.tongji.housediy.model.FloorModel;
	import com.tongji.housediy.model.SelectedObjectModel;
	import com.tongji.housediy.model.ViewControlModel;
	import com.tongji.housediy.utils.CollisionDetection;
	import com.tongji.housediy.utils.ConstVariableInventory;
	import com.tongji.housediy.utils.MathCalculation;
	import com.tongji.housediy.view.Room3DMediator;
	import com.tongji.housediy.view.components.GridContainer;
	
	import de.polygonal.ds.DListNode;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Mouse;
	import flash.ui.MouseCursor;
	
	import mx.controls.Alert;
	import mx.core.IUIComponent;
	import mx.core.UIComponent;
	import mx.events.CloseEvent;
	import mx.events.DragEvent;
	import mx.managers.DragManager;
	
	import org.robotlegs.mvcs.Mediator;
	
	import spark.components.List;
	
	/**
	 * 
	 * @author chenchao
	 * 
	 */
	public class GridContainerMediator extends Mediator
	{
		[Inject]
		public var view:GridContainer;
		
		[Inject]
		public var exchangeDataModel:ExchangeDataModel;
		
		[Inject]
		public var selectedModel:SelectedObjectModel;
		
		[Inject]
		public var viewControlModel:ViewControlModel;
		
		private var tempX:Number;
		private var tempY:Number;
		
		protected var offsetX:Number;
		protected var offsetY:Number;
		
		private var tempMatrix:Matrix;
		
		//private var acceptAllFormat:Array = ["roomFormat", "independentFloor"];
		private var acceptAllFormat:Array = ["roomFormat"];
		
		private var roomProxy:RoomFloor;
		
		[Embed(source="assets/images/warning.png")]
		private var BulletCritical:Class;
		
		override public function onRegister():void
		{
			this.addContextListener(GridContainerEvent.START_MOVE_LEFT, gridMoveLeftHandler, GridContainerEvent);
			this.addContextListener(GridContainerEvent.START_MOVE_RIGHT, gridMoveRightHandler, GridContainerEvent);
			this.addContextListener(GridContainerEvent.START_MOVE_UP, gridMoveUpHandler, GridContainerEvent);
			this.addContextListener(GridContainerEvent.START_MOVE_DOWN, gridMoveDownHandler, GridContainerEvent);
			this.addContextListener(GridContainerEvent.STOP_MOVE, gridStopMoveHandler, GridContainerEvent);
			
			this.addContextListener(GridContainerEvent.UPDATE_GRID_SCALE, gridScaleHandler, GridContainerEvent);
			
			this.addContextListener(BeginDrawFreeFloorEvent.DRAW_FREE_FLOOR, drawFreeFloor);
			
			this.addContextListener(RulerAdminEvent.SHOW_HIDE_RULERS, showHideBorderRuler);
			
			view.addEventListener(MouseEvent.MOUSE_WHEEL, gridMouseWheelHandler);
			
			view.addEventListener(DragEvent.DRAG_ENTER, viewDragEnterHandler);
			view.addEventListener(DragEvent.DRAG_DROP, viewDragDropHandler);
			view.addEventListener(DragEvent.DRAG_OVER, viewDragOverHandler);
			
			view.addEventListener(RotationRelatedEvent.SHOW_ROTATION_BTN, showRotationBtnHandler);
			view.addEventListener(RotationRelatedEvent.HIDE_ROTATION_BTN, hideRotationBtnHandler);
			this.addContextListener(RotationRelatedEvent.HIDE_ROTATION_BTN, hideRotationBtnHandler, RotationRelatedEvent);
			
			view.addEventListener(ExchangeDataEvent.UPDATE_EXCHANGE_MODEL, setExchangeModel);
			
			this.addContextListener(RulerAdminEvent.HIDE_ALL_RULERS, hideRulersHandler);
			
			view.addEventListener(ShowVertexEvent.SHOW_VERTEX, showVertexHandler);
			
			view.addEventListener(CursorBitmapEvent.SHOW_CUSTOM_CURSOR, showCustomHandler);
			view.addEventListener(CursorBitmapEvent.UPDATE_CUSTOM_CURSOR, updateCustomHandler);
			view.addEventListener(CursorBitmapEvent.HIDE_CUSTOM_CURSOR, hideCustomHandler);
			
			view.addEventListener(RulerAdminEvent.ADD_RULER, addRulerHandler);
			view.addEventListener(RulerAdminEvent.HIDE_ALL_RULERS, hideRulersHandler);
			
			view.addEventListener(ShowHideTitleWindowEvent.SHOW_TITLE_WINDOW, showTitleWindowHandler);
			view.addEventListener(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW, hideTitleWindowHandler);
			
			view.addEventListener(ShowHideFilterEvent.HIDE_FILTER, showFilterHandler);
			
			this.addContextListener(ShowHideTitleWindowEvent.UPDATE_LINE_POSITION, updateLinePositionHandler, ShowHideTitleWindowEvent);
			this.addContextListener(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW, hideTitleWindowHandler, ShowHideTitleWindowEvent);
			
			view.addEventListener(MouseEnabledAdminEvent.MOUSE_ENABLED_OPENED, openMouseChildrenHandler);
			view.addEventListener(MouseEnabledAdminEvent.MOUSE_ENABLED_CLOSED, closeMouseChildrenHandler);
			this.addContextListener(MouseEnabledAdminEvent.MOUSE_ENABLED_OPENED, openMouseChildrenHandler, MouseEnabledAdminEvent);
			this.addContextListener(MouseEnabledAdminEvent.MOUSE_ENABLED_CLOSED, closeMouseChildrenHandler, MouseEnabledAdminEvent);
			
			this.addContextListener(RoomNameAdminEvent.SHOW_HIDE_ROOM_NAME, showHideRoomNameHandler, RoomNameAdminEvent);
			this.addContextListener(RoomNameAdminEvent.HIDE_ROOM_NAME, hideRoomNameHandler, RoomNameAdminEvent);
			view.addEventListener(RoomNameAdminEvent.HIDE_ROOM_NAME, hideRoomNameHandler);
			
			view.addEventListener(RelatedRoomAdminEvent.UPDATE_RELATED_ROOM, updateRelatedRoomHandler);
			
			view.stage.addEventListener(KeyboardEvent.KEY_DOWN, gridContainerKeyDownHandler);
			
			view.addEventListener(SetCompStateEvent.RESET_FILTER, reset);
			//this.addContextListener(SetCompStateEvent.RESET_FILTER, reset,SetCompStateEvent);
		}
		
		public function showFilterHandler(event:ShowHideFilterEvent):void
		{
			event.host.filters = null;
		}
		
		public function reset(event:SetCompStateEvent):void
		{
			for (var i:int = 0; i < view.numChildren; i++)
			{
				if (view.getChildAt(i) is RoomBorder)
					(view.getChildAt(i) as RoomBorder).filters = null;
			}					
		}
		private function showTitleWindowHandler(event:ShowHideTitleWindowEvent):void
		{
			var lineData:Vector.<Number> = new Vector.<Number>();
			lineData.push(event.firstX, event.firstY, event.secondX, event.secondY);
			
			if (view.infoLine && view.contains(view.infoLine))
			{
				view.infoLine.reDrawing(lineData);
			}
			else
			{
				view.infoLine = new InfoLine(lineData);
				view.addChild(view.infoLine);
			}
		}
		
		private function hideTitleWindowHandler(event:ShowHideTitleWindowEvent):void
		{
			if (view.infoLine && view.contains(view.infoLine))
				view.removeChild(view.infoLine);
		}
		
		private function updateLinePositionHandler(event:ShowHideTitleWindowEvent):void
		{
			view.infoLine.resetSecondPoint(view.globalToLocal(new Point(event.secondX, event.secondY)));
		}
		
		private function gridMoveLeftHandler(event:GridContainerEvent):void
		{
			view.isMoveLeft = true;
			view.addEventListener(Event.ENTER_FRAME, moveGridContainer);
		}
		
		private function gridMoveRightHandler(event:GridContainerEvent):void
		{
			view.isMoveRight = true;
			view.addEventListener(Event.ENTER_FRAME, moveGridContainer);
		}
		
		private function gridMoveUpHandler(event:GridContainerEvent):void
		{
			view.isMoveUp = true;
			view.addEventListener(Event.ENTER_FRAME, moveGridContainer);
		}
		
		private function gridMoveDownHandler(event:GridContainerEvent):void
		{
			view.isMoveDown = true;
			view.addEventListener(Event.ENTER_FRAME, moveGridContainer);
		}
		
		private function gridStopMoveHandler(event:GridContainerEvent):void
		{
			view.isMoveLeft = false;
			view.isMoveRight = false;
			view.isMoveUp = false;
			view.isMoveDown = false;
			view.removeEventListener(Event.ENTER_FRAME, moveGridContainer);
		}
		
		private function moveGridContainer(event:Event):void
		{
			if (view.isMoveLeft) view.moveGridContainer(-ConstVariableInventory.MOVE_DISTANCE, 0);
			if (view.isMoveRight) view.moveGridContainer(ConstVariableInventory.MOVE_DISTANCE, 0);
			if (view.isMoveUp) view.moveGridContainer(0, -ConstVariableInventory.MOVE_DISTANCE);
			if (view.isMoveDown) view.moveGridContainer(0, ConstVariableInventory.MOVE_DISTANCE);
		}
		
		private function gridScaleHandler(event:GridContainerEvent):void
		{
			if (event.isWheel)
				view.scaleGridContainer(view.parent.mouseX, view.parent.mouseY, Math.pow(ConstVariableInventory.WHEEL_SCALE_UP, event.scaleMultiple));
			else
				view.scaleGridContainer(view.parent.width / 2, view.parent.height / 2, Math.pow(ConstVariableInventory.WHEEL_SCALE_UP, event.scaleMultiple));
			
			// 派发更新 RatioComp 事件
			dispatch(new UpdateRatioCompEvent(UpdateRatioCompEvent.UPATE_RATIO_COMP, event.scaleMultiple));
			
			// 隐藏 TitleWindow
			dispatch(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.HIDE_TITLE_WINDOW));
		}
		
		private function gridMouseWheelHandler(event:MouseEvent):void
		{
			if (event.delta > 0)
			{
				viewControlModel.dimensionValue +=1;
				dispatch(new GridContainerEvent(GridContainerEvent.UPDATE_SCROLL_VALUE, 1));
			}
			else if (event.delta < 0)
			{
				viewControlModel.dimensionValue -=1;
				dispatch(new GridContainerEvent(GridContainerEvent.UPDATE_SCROLL_VALUE, -1));
			}
		}
		
		private function viewDragEnterHandler(event:DragEvent):void
		{
			if (acceptAllFormat.indexOf(event.dragSource.formats[0]) != -1)
			{
				DragManager.acceptDragDrop(IUIComponent(event.target));
				this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_UNABLE,0));
				//****************************************this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_ENABLE));
			}
		}
		
		private function viewDragDropHandler(event:DragEvent):void
		{
			var room:AbstractDrawingRoom = event.dragSource.dataForFormat(event.dragSource.formats[0]) as AbstractDrawingRoom;
			room.scaleX = 1;
			room.scaleY = 1;
			room.parentGridContainer = view;
			room.x = view.mouseX;
			room.y = view.mouseY;
			
			view.addChild(room);
			var j:int = 0;
			for (var i:int = 0; i < view.numChildren; i++)
			{
				if (view.getChildAt(i) is AbstractDrawingRoom)
				{
					j++;
				}
			}
			this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_ENABLE, j));
			//this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_ENABLE));
		}
		
		private function viewDragOverHandler(event:DragEvent):void
		{
			var collisionRoom:AbstractDrawingRoom = event.dragSource.dataForFormat(event.dragSource.formats[0]) as AbstractDrawingRoom;
			
			if (!(collisionRoom is IndependentFloor) && isCollision(collisionRoom.roomFloor))
				DragManager.showFeedback(DragManager.NONE);
			else
				DragManager.showFeedback(DragManager.MOVE);
			
		}
		
		private function isCollision(collisionFloor:RoomFloor):Boolean
		{
			for (var i:int = 0; i < view.numChildren; i++)
			{
				if (!(view.getChildAt(i) is RotationBtn))
				{
					var currentRoom:AbstractDrawingRoom = view.getChildAt(i) as AbstractDrawingRoom;
					if (CollisionDetection.complexHitTestObject(collisionFloor, currentRoom.roomFloor))
					{
						return true;
					}
				}
			}
			return false;
		}
		
		private function drawFreeFloor(event:Event):void
		{
			var freeFormComponent:FreeFormComponent = new FreeFormComponent();
			view.addChild(freeFormComponent);
			freeFormComponent.startDrawing();
			Mouse.cursor = MouseCursor.IBEAM;
		}
		
		private function showRotationBtnHandler(event:RotationRelatedEvent):void
		{
			view.addChild(view.rotationBtn);
			view.rotationBtn.x = event.initialX;
			view.rotationBtn.y = event.initialY;
			view.rotationBtn.relatedObj = event.room;
		}
		
		private function hideRotationBtnHandler(event:RotationRelatedEvent):void
		{
			view.hideRotationBtn();
		}
		
		private function setExchangeModel(event:ExchangeDataEvent):void
		{
			dispatch(new ExchangeDataEvent(ExchangeDataEvent.UPDATE_EXCHANGE_MODEL));
		}
		
		private function showHideBorderRuler(event:RulerAdminEvent):void
		{
			if (!view.contains(view.rulerContainer))
			{
				for (var i:int = 0; i < view.numChildren; i++)
				{
					if (view.getChildAt(i) is AbstractDrawingRoom)
					{
						var room:AbstractDrawingRoom = view.getChildAt(i) as AbstractDrawingRoom;
						room.showHideRuler();
						
						for (var j:int = 0; j < room.roomFloor.numChildren; j++)
						{
							if (room.roomFloor.getChildAt(j) is IndependentFloor)
								(room.roomFloor.getChildAt(j) as IndependentFloor).showHideRuler();
							else if (room.roomFloor.getChildAt(j) is InteriorWall)
								(room.roomFloor.getChildAt(j) as InteriorWall).showHideRuler();
						}
					}
				}
			}
			else
				hideRulersHandler(event);
		}
		
		private function showHideRoomNameHandler(event:RoomNameAdminEvent):void
		{
			if (!view.contains(view.roomNameContainer))
			{
				view.roomNameContainer.init(view);
				view.addChild(view.roomNameContainer);
				var j:int = 0;
				for (var i:int = 0; i < view.numChildren; i++)
				{
					if (view.getChildAt(i) is AbstractDrawingRoom)
					{
						j++;
					}
				}
				this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_ENABLE, j));
			}
			else
			{
				view.removeChild(view.roomNameContainer);
				//this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_UNABLE));
			}
		}
		
		private function hideRoomNameHandler(event:RoomNameAdminEvent):void
		{
			if (view.contains(view.roomNameContainer))
			{
				view.removeChild(view.roomNameContainer);
				//this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_UNABLE));
			}
		}
		
		private function addRulerHandler(event:RulerAdminEvent):void
		{
			if (event.array.length == 7)
			{
				if (event.array[6] == "external")
				{
					if (event.array[5] != -1)
					{
						(view.rulerContainer.getChildAt(event.array[5]) as ExternalRulerField).updateRulerField(event.array[0], event.array[1], event.array[2], event.array[3], event.array[4]);
					}
					else
					{
						var externalRuler:ExternalRulerField = new ExternalRulerField(event.array[0], event.array[1], event.array[2], event.array[3], event.array[4]);
						view.rulerContainer.addChild(externalRuler);
					}
				}
				else
				{
					var internalRuler:InternalRulerField = new InternalRulerField(event.array[0], event.array[1], event.array[2], event.array[3], event.array[4]);
					view.rulerContainer.addChild(internalRuler);
				}
			}
			else
			{
				if (!view.contains(view.rulerContainer))
				{
					var internalRuler1:InternalRulerField = new InternalRulerField(event.array[0], event.array[1], event.array[2], event.array[3], event.array[4]);
					view.rulerContainer.addChild(internalRuler1);
					var internalRuler2:InternalRulerField = new InternalRulerField(event.array[7], event.array[8], event.array[9], event.array[10], event.array[11]);
					view.rulerContainer.addChild(internalRuler2);
					var internalRuler3:InternalRulerField = new InternalRulerField(event.array[14], event.array[15], event.array[16], event.array[17], event.array[18]);
					view.rulerContainer.addChild(internalRuler3);
				}
				else
				{
					(view.rulerContainer.getChildAt(0) as InternalRulerField).updateRulerField(event.array[0], event.array[1], event.array[2], event.array[3], event.array[4]);
					(view.rulerContainer.getChildAt(1) as InternalRulerField).updateRulerField(event.array[7], event.array[8], event.array[9], event.array[10], event.array[11]);
					(view.rulerContainer.getChildAt(2) as InternalRulerField).updateRulerField(event.array[14], event.array[15], event.array[16], event.array[17], event.array[18]);
				}
			}
			
			if (!view.contains(view.rulerContainer)) view.addChild(view.rulerContainer);
		}
		
		private function hideRulersHandler(event:RulerAdminEvent):void
		{
			if (view.contains(view.rulerContainer))
			{
				while (view.rulerContainer.numChildren > 0)
				{
					var removeRulerField:Sprite = view.rulerContainer.removeChildAt(0) as Sprite;
					removeRulerField = null;
				}
				view.removeChild(view.rulerContainer);
			}
			
			if (event.hostRoom) event.hostRoom.showRuler();
		}
		
		private function showVertexHandler(event:ShowVertexEvent):void
		{
			for (var i:int = 0; i < view.numChildren; i++)
			{
				if (view.getChildAt(i) is AbstractDrawingRoom)
				{
					if (view.getChildAt(i) == event.hostBorder.parent)
						(view.getChildAt(i) as AbstractDrawingRoom).showVertex(event.hostBorder as RoomBorder);
					else
						(view.getChildAt(i) as AbstractDrawingRoom).hideVertex();
				}
			}
		}
		
		private function showCustomHandler(event:CursorBitmapEvent):void
		{
			switch (event.bitmapType)
			{
				case "center":
					view.cursorBitmap = view.centerCursor;
					break;
				case "horizontal":
					view.cursorBitmap = view.verticalCursor;
					break;
				case "vertical":
					view.cursorBitmap = view.horizontalCursor;
					break;
			}
			view.addChild(view.cursorBitmap);
			view.cursorBitmap.x = event.xPosition - view.cursorBitmap.width / 2;
			view.cursorBitmap.y = event.yPosition - view.cursorBitmap.height / 2;
			Mouse.hide();
		}
		
		private function updateCustomHandler(event:CursorBitmapEvent):void
		{
			if (view.cursorBitmap && view.contains(view.cursorBitmap))
			{
				view.cursorBitmap.x = event.xPosition - view.cursorBitmap.width / 2;
				view.cursorBitmap.y = event.yPosition - view.cursorBitmap.height / 2;
			}
		}
		
		private function hideCustomHandler(event:CursorBitmapEvent):void
		{
			if (view.cursorBitmap && view.contains(view.cursorBitmap)) view.removeChild(view.cursorBitmap);
			Mouse.show();
		}
		
		private function openMouseChildrenHandler(event:MouseEnabledAdminEvent):void
		{
			view.mouseChildren = true;
		}
		
		private function closeMouseChildrenHandler(event:MouseEnabledAdminEvent):void
		{
			view.mouseChildren = false;
		}
		
		private function updateRelatedRoomHandler(event:RelatedRoomAdminEvent):void
		{
			dispatch(new RelatedRoomAdminEvent(RelatedRoomAdminEvent.UPDATE_RELATED_ROOM, event.dragedRoom, event.oppositedRoomVector));
		}
		
		private function gridContainerKeyDownHandler(event:KeyboardEvent):void
		{
			if (selectedModel.selectedObj)
			{
				switch (event.keyCode)
				{
					case 37:
						if ((selectedModel.selectedObj as RoomShape).moveShape(-1, 0))
						{
							view.infoLine.addOffsetPoint(-1, 0);
							view.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.UPDATE_TITLE_WINDOW_POSITION, -1, 0));
						}
						break;
					case 38:
						if ((selectedModel.selectedObj as RoomShape).moveShape(0, -1))
						{
							view.infoLine.addOffsetPoint(0, -1);
							view.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.UPDATE_TITLE_WINDOW_POSITION, 0, -1));
						}
						break;
					case 39:
						if ((selectedModel.selectedObj as RoomShape).moveShape(1, 0))
						{
							view.infoLine.addOffsetPoint(1, 0);
							view.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.UPDATE_TITLE_WINDOW_POSITION, 1, 0));
						}
						break;
					case 40:
						if ((selectedModel.selectedObj as RoomShape).moveShape(0, 1))
						{
							view.infoLine.addOffsetPoint(0, 1);
							view.dispatchEvent(new ShowHideTitleWindowEvent(ShowHideTitleWindowEvent.UPDATE_TITLE_WINDOW_POSITION, 0, 1));
						}
						break;
					case 46:
					{
						var alert:Alert;
						alert = Alert.show("确定要删除吗？", "删除房间?", Alert.OK | Alert.CANCEL, view.stage as Sprite, alertClickHandler);
						alert.titleIcon = BulletCritical;
					}
						
						break;
				}
			}
		}
		
		private function alertClickHandler(event:CloseEvent):void
		{
			if (event.detail == Alert.OK)
			{
				selectedModel.deleteSelectedObj();
				//this.dispatch(new SetShowNameEnable(SetShowNameEnable.SET_SHOW_NAME_UNABLE, )
			}
		}
	}
}